/**
 * UltraCSA平台系统文件
 * 
 * Copyright 2015 北京神州泰岳软件股份有限公司
 */
package com.ultrapower.ultracsa.product.util.dynamic;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.ultrapower.ultracsa.product.conf.ProjectPathCfg;


/**
 * 作者: yangjie
 * 
 * 日期: 2015
 * 
 * 版权说明：北京神州泰岳软件股份有限公司
 * 
 * 用于工程中动态加载Class类
 */
public class DynamicUpdateServer {
	private static Logger log = Logger.getLogger(DynamicUpdateServer.class);
	private List<URL> jarFile=new ArrayList();
	private Map<String,Long> lastUpdate=new HashMap();
	private Map<String,Class> classMap=new HashMap();
	private static DynamicUpdateServer server=null;
	private ClassLoader loader=null;
	/**
	 * 用于标记是否为开发环境，开发环境时，接口类从classpath中直接读取
	 * 发布环境时，接口类从：$Tomcat$/dynamic 目录中读取
	 */
	private boolean isDevEnv=true;
	
	private DynamicUpdateServer(){
		if(!isDevEnv){
			loadFile();
			start();
		}
	}
	
	public static synchronized DynamicUpdateServer getInstance(){
		if(server==null)
			server=new DynamicUpdateServer();
		return server;
	}
	
	private void loadFile(){
		try {
			File[] fileList=new File(ProjectPathCfg.getDynamicPath()).listFiles();
			for (File file : fileList) {
			    if(file.getName().toLowerCase().endsWith(".jar")){
			        jarFile.add(file.toURI().toURL());
			        lastUpdate.put(file.toURI().toString(), new Long(file.lastModified()));
			    }
			}
			
			if(jarFile.size()>0){
				URL[] urls=jarFile.toArray(new URL[jarFile.size()]);
//				loader=URLClassLoader.newInstance(urls);
				loader=URLClassLoader.newInstance(urls,DynamicUpdateServer.class.getClassLoader());
			}else
				loader=URLClassLoader.getSystemClassLoader();
			
		} catch (Exception e) {
			log.error("",e);
		}
		
	}
	
	private void start(){
		Thread t=new Thread(){
			public void run(){
				if(jarFile!=null){
					while(true){
						boolean updated=false;
						File[] fileList=new File(ProjectPathCfg.getDynamicPath()).listFiles();
						URL jar=null;
						for (File file : fileList) {
							String uri=file.toURI().toString();
							try {
								jar=file.toURI().toURL();
								if(!jarFile.contains(jar)){
									updated=true;
									jarFile.add(jar);
									lastUpdate.put(uri, new Long(file.lastModified()));
								}else{
									if(lastUpdate.get(uri).longValue()!=file.lastModified()){
										updated=true;
										lastUpdate.put(uri, new Long(file.lastModified()));
									}
								}
							} catch (MalformedURLException e) {
								log.error("", e);
							}							
						}
						
						if(updated){
							synchronized(loader){
								log.info("更新URLClassLoader成功！");
								URL[] urls=jarFile.toArray(new URL[jarFile.size()]);
								loader=URLClassLoader.newInstance(urls,DynamicUpdateServer.class.getClassLoader());
								classMap.clear();
							}
						}
						
						try {
							sleep(1000*10);
						} catch (InterruptedException e) {
							log.error("",e);
						}
					}
				}else
					loader=URLClassLoader.getSystemClassLoader();
			}
		};
		t.start();
	}
	
	public Class getNewClass(String className){
		try {
			if(isDevEnv)
				return Class.forName(className);
			else{
			if(!classMap.containsKey(className)){
				Class temp=loader.loadClass(className);
				if(temp==null)
					temp=System.class.getClassLoader().getSystemClassLoader().loadClass(className);
				classMap.put(className, temp);
			}
			return classMap.get(className);
			}
		} catch (Exception e) {
			log.error("",e);
			return null;
		}
	}
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
